import { CountUp as CU } from "./countUp";
import { PropType, defineComponent, onMounted, onUnmounted, ref, watch } from "vue";

interface CountUpProps {
    value: number | string; // 目标值
    start?: number; // 起始值
    duration?: number; // 动画持续时间
    decimal?: number; // 小数位数
    useGrouping?: boolean; // 是否使用千位分隔符
    useEasing?: boolean; // 是否使用缓动效果
    separator?: string; // 千位分隔符
    formattingFn?: (n: number) => string; // 自定义格式化函数
    prefix?: string; // 前缀文本
    suffix?: string; // 后缀文本
    onEnd?: () => void; // 动画结束回调
}
/**
 *
 * @param props
 * @returns
 */
export default defineComponent({
    name: 'CountUp',
    props: {
        value: {type: [Number, String] as PropType<CountUpProps['value']>, default: 0},
        start: {type: Number as PropType<CountUpProps['start']>, default: 0},
        duration: {type: Number as PropType<CountUpProps['duration']>, default: 2},
        decimal: {type: Number as PropType<CountUpProps['decimal']>, default: 0},
        useGrouping: {type: Boolean as PropType<CountUpProps['useGrouping']>, default: true},
        useEasing: {type: Boolean as PropType<CountUpProps['useEasing']>, default: true},
        separator: {type: String as PropType<CountUpProps['separator']>, default: ','},
        formattingFn: {type: Function as PropType<CountUpProps['formattingFn']>},
        prefix: {type: String as PropType<CountUpProps['prefix']>, default: ''},
        suffix: {type: String as PropType<CountUpProps['suffix']>, default: ''},
    },
    emits: ['end'],
    setup (props, {emit, expose}) {
        const target = ref<HTMLElement | null>(null); // 目标 DOM 元素
        const instance = ref<CU | null>(null); // CountUp 实例

        // 初始化 CountUp 实例
        const initCountUp = () => {
            if (!target.value) return;

            console.log(111);

            const options = {
                startVal: props.start,
                duration: props.duration,
                decimalPlaces: props.decimal,
                useGrouping: props.useGrouping,
                useEasing: props.useEasing,
                separator: props.separator,
                formattingFn: props.formattingFn,
                prefix: props.prefix,
                suffix: props.suffix,
                onCompleteCallback: () => emit('end'),
            };

            instance.value = new CU(target.value, parseFloat(props.value as string), options);

            if (instance.value.error) {
                console.error(instance.value.error);
            } else {
                instance.value.start();
            }
        };

        // 更新目标值
        const update = (val: number) => {
            instance.value?.update(val);
        };

        // 暂停/恢复动画
        const pauseResume = () => {
            instance.value?.pauseResume();
        };

        // 重置动画
        const reset = () => {
            instance.value?.reset();
        };

        const start = () => {
            instance.value?.start();
        };

        // 生命周期钩子
        onMounted(initCountUp);
        onUnmounted(() => {
            if (instance.value) {
                instance.value = null;
            }
        });

        // 监听 value 变化
        watch(() => props.value, (val) => {
            update(parseFloat(val as string));
        });

        // 暴露方法
        expose({ reset, update, start, pauseResume });

        return () => <span class="cm-count-up" ref={target}></span>;
    },
});
